package com.huanzhidadi.single.enums;

import com.alibaba.fastjson2.JSON;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class TwoLayerEnumTest {
    public static void main(String[] args) {
        List<SpecBO> BOList = ChildEnum.getChildTypeEnumList();
        log.info(JSON.toJSONString(BOList));

        SpecBO specBO = ChildEnum.getItemEumByCode("CHILD21");
        log.info(JSON.toJSONString(specBO));
    }
}

enum ParentEnum {

    PARENT1("CODE1", "父级1", "CODE1"),
    PARENT2("CODE2", "父级2", "CODE2");


    // 编码
    private final String code;
    // 名称
    private final String name;
    // 分组标记
    private final String tag;

    ParentEnum(String code, String name, String tag) {
        this.code = code;
        this.name = name;
        this.tag = tag;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public String getTag() {
        return tag;
    }

    public static Boolean hasTag(String tag) {
        return  Arrays.stream(ParentEnum.values()).anyMatch(i->i.getTag().equals(tag));
    }

    public static SpecBO getItemEumByTag(String tag) {
        SpecBO specBO  = new SpecBO();
        Arrays.stream(ParentEnum.values()).forEach(i->{
            if(i.getTag().equals(tag)){
                specBO.setCode(i.getCode());
                specBO.setName(i.getName());
                specBO.setTag(tag);
            }
        });
        return specBO;
    }
}

enum ChildEnum {

    CHILD11("CHILD11", "子级11", ParentEnum.PARENT1.getTag()),
    CHILD12("CHILD12", "子级12", ParentEnum.PARENT1.getTag()),
    CHILD21("CHILD21", "子级21", ParentEnum.PARENT2.getTag()),
    CHILD22("CHILD22", "子级22", ParentEnum.PARENT2.getTag());


    // 编码
    private final String code;
    // 名称
    private final String name;
    // 分组标记
    private final String tag;

    ChildEnum(String code, String name, String tag) {
        this.code = code;
        this.name = name;
        this.tag = tag;
    }

    public String getCode() {
        return code;
    }

    public String getName() {
        return name;
    }

    public String getTag() {
        return tag;
    }

    public static SpecBO getItemEumByCode(String code) {
        SpecBO specBO = new SpecBO();
        Arrays.stream(ChildEnum.values()).forEach(i->{
            if(i.getCode().equals(code)){
                specBO.setCode(code);
                specBO.setName(i.getName());
                specBO.setTag(i.getTag());
                SpecBO parentItem = ParentEnum.getItemEumByTag(i.getTag());
                specBO.setParentCode(parentItem.getCode());
                specBO.setParentName(parentItem.getName());
            }
        });
        return specBO;
    }

    public static List<SpecBO> getChildTypeEnumList() {
        final List<SpecBO> li = new ArrayList<>();
        Arrays.stream(ChildEnum.values()).forEach(s->{
            if(ParentEnum.hasTag(s.getTag())) {
                // 获取一级 如果li中未找到当前循环的Tag，则把对应的parent加入li
                if(!li.stream().anyMatch(an->an.getTag().equals(s.getTag()))){
                    li.add(ParentEnum.getItemEumByTag(s.getTag()));
                }
                //组装二级 循环的是li，如果li中找到了当前循环的s的Tag，则把对应的child加入li当前循环到的l的childList
                li.stream().forEach(l->{
                    if(l.getTag().equals(s.getTag())){
                        l.getChildList().add(getItemEumByCode(s.getCode()));
                    }
                });
            }
        });
        // 可以根据情况对结果进行排序处理
        /*return li.stream().sorted(Comparator.comparing(BO::getTag)
                .thenComparing(BO::getCode)
                .thenComparing(BO::getName)).collect(Collectors.toList());*/
        return li.stream().collect(Collectors.toList());
    }
}

@Data
class SpecBO {

    private String code;

    private String name;

    private String tag;

    private String parentCode;

    private String parentName;

    private List<SpecBO> childList = new ArrayList<>();
}